/********************************
 * tools for epoll and mod add del the events
 *
 * created by dirkcai
 * *******************************/
#include "epollmanager.h"
#include "buffersocket.h"
#include <stdio.h>


EpollManager :: EpollManager( int listenfd, int iEpollSize, int iWaitSize )
{
	assert( iEpollSize > 0 );
	assert( iWaitSize > 0 );
	m_listenfd = listenfd;
	m_iEpollSize = iEpollSize;
	m_iEpoll_Mode = EPOLLET;
	m_iWaitSize = iWaitSize;
	m_ptEvents = new epoll_event [ iWaitSize ];
}

EpollManager :: ~EpollManager()
{
	if ( m_ptEvents != NULL )
	{
		delete []m_ptEvents;
		m_ptEvents = NULL;
	}
}

int EpollManager :: Init()
{
	int ret = -1;
	m_epollfd = epoll_create( m_iEpollSize );
	if ( m_epollfd >  0 )
	{
		BufferSocket * ptBufSocket = new BufferSocket(m_listenfd);
		ret = AddEvent( m_listenfd, EPOLLIN, ptBufSocket);
	}
	return ret;
}

int EpollManager :: WaitEvents( int timeout )
{
	m_iNfds = epoll_wait( m_epollfd, m_ptEvents, m_iWaitSize, timeout );
	return m_iNfds;
}

int EpollManager :: AddEvent( int connfd, int iEventType, BufferSocket * ptBufSocket )
{
	struct epoll_event event;
	event.data.ptr = (void *) ptBufSocket;
	event.events = iEventType|m_iEpoll_Mode;
	return epoll_ctl( m_epollfd, EPOLL_CTL_ADD, connfd, &event);
}

int EpollManager :: DelEvent( int connfd, int iEventType, BufferSocket * ptBufSocket )
{
	struct epoll_event event;
	event.data.ptr = (void *) ptBufSocket;
	event.events = iEventType|m_iEpoll_Mode;
	epoll_ctl( m_epollfd, EPOLL_CTL_DEL, connfd, &event);
	close(connfd);
	return 0;
}

int EpollManager :: Mod2W( int connfd, BufferSocket * ptBufSocket ) 
{
	struct epoll_event event;
	event.data.ptr = (void *) ptBufSocket;
	event.events = EPOLLOUT|m_iEpoll_Mode;
	return epoll_ctl( m_epollfd, EPOLL_CTL_MOD, connfd, &event);
}

int EpollManager :: Mod2R( int connfd, BufferSocket * ptBufSocket )
{
	struct epoll_event event;
	event.data.ptr = (void *) ptBufSocket;
	event.events = EPOLLIN|m_iEpoll_Mode;
	return epoll_ctl( m_epollfd, EPOLL_CTL_MOD, connfd, &event );
}

epoll_event * EpollManager :: GetEventByPos( int index ) 
{
	if ( index >= 0 && index < m_iNfds )
	{
		return &(m_ptEvents[index]);
	}
	return NULL;
}

int EpollManager :: GetListenFd()
{
	return m_listenfd;
}
